package org.koin.core;

import org.junit.Assert;
import org.junit.Test;
import org.koin.Simple;
import org.koin.core.definition.Definition;
import org.koin.core.error.*;
import org.koin.core.parameter.DefinitionParameters;
import org.koin.core.scope.Scope;
import org.koin.dsl.KoinAppDeclaration;
import org.koin.dsl.Module;
import org.koin.dsl.ModuleDeclaration;

import static org.koin.dsl.KoinApplication.koinApplication;

public class LazyInstanceResolution {

    @Test
    public void can_lazy_resolve_a_single() throws ScopeAlreadyCreatedException, NoScopeDefFoundException, DefinitionParameterException, NoBeanDefFoundException, ClosedScopeException {

        KoinApplication app = koinApplication(new KoinAppDeclaration() {
            @Override
            public void invoke(KoinApplication koinApplication) {

                org.koin.core.module.Module module = Module.module(new ModuleDeclaration() {
                    @Override
                    public void invoke(org.koin.core.module.Module module) {
                        try {
                            module.single(Simple.ComponentA.class, new Definition<Simple.ComponentA>() {
                                @Override
                                public Simple.ComponentA invoke(Scope scope, DefinitionParameters parameters) {
                                    return new Simple.ComponentA();
                                }
                            });
                        } catch (DefinitionOverrideException e) {
                            e.printStackTrace();
                        }
                    }
                });

                try {
                    koinApplication.modules(module);
                } catch (DefinitionOverrideException e) {
                    e.printStackTrace();
                }
            }
        });

        Koin koin = app.getKoin();
        Simple.ComponentA a = koin.<Simple.ComponentA>get(Simple.ComponentA.class);
        Simple.ComponentA a2 = koin.<Simple.ComponentA>get(Simple.ComponentA.class);

        Assert.assertEquals(a, a2);
    }
}
